package znet

import (
	"fmt"
	"tcpChat/conf"
	"tcpChat/ziface"
)

type MsgHandler struct {
	Apis           map[uint32]ziface.IRouter //msgId对应的回调处理函数
	WorkerPoolSize uint32                    //业务工作池中worker数量
	TaskQueue      []chan ziface.IRequest    //任务中的消息队列
}

func NewMsgHandler() *MsgHandler {
	return &MsgHandler{
		Apis:           make(map[uint32]ziface.IRouter),
		WorkerPoolSize: conf.GlobalObject.WorkerPoolSize,
		//一个worker对应一个queue
		TaskQueue: make([]chan ziface.IRequest, conf.GlobalObject.WorkerPoolSize),
	}
}

func (m *MsgHandler) StartOneWorker(workId int, taskQueue chan ziface.IRequest) {
	fmt.Println(fmt.Sprintf("Work ID %d is starting", workId))

	for {
		select {
		//从taskqueue管道获取请求数据
		case request := <-taskQueue:
			//执行对应的方法
			m.DoMsgHandler(request)
		}
	}
}

func (m *MsgHandler) StartWorkerPool() {
	//创建工作池
	for i := 0; i < int(conf.GlobalObject.WorkerPoolSize); i++ {
		//创建队列空间
		m.TaskQueue[i] = make(chan ziface.IRequest, conf.GlobalObject.MaxWorkerTaskLen)
		//携程开启工作池任务
		go m.StartOneWorker(i, m.TaskQueue[i])
	}
}

//以阻塞的方式处理消息
func (m *MsgHandler) DoMsgHandler(request ziface.IRequest) {
	handler, ok := m.Apis[request.GetMsgId()]
	if ok != true {
		fmt.Println(fmt.Sprintf("API msgId : %d is not find", request.GetMsgId()))
		return
	}

	//执行对应的方法
	handler.PreHandle(request)
	handler.Handle(request)
	handler.PostHandel(request)
}

func (m *MsgHandler) SendMsgToTaskQueue(request ziface.IRequest) {
	//根据请求ID,取余分配到TaskQueue队列中
	workId := request.GetConnection().GetConnId() % conf.GlobalObject.WorkerPoolSize
	fmt.Println(fmt.Sprintf("TASK队列[%d],添加消息: ID[%d], 消息：%s", workId, request.GetMsgId(), string(request.GetData())))
	m.TaskQueue[workId] <- request
}

//添加消息对应的处理逻辑
func (m *MsgHandler) AddRouter(msgId uint32, router ziface.IRouter) {
	if _, ok := m.Apis[msgId]; ok {
		fmt.Println(fmt.Sprintf("API MAP add msgID FAIL, msgId = %d", msgId))
	}

	m.Apis[msgId] = router
}
